#include "stdafx.h"
#include "inputmanager.h"
#include "gamemanager.h"
#include "DXUT.h"
#include "texture.h"
#include "MapManager.h"

CInputManager::CInputManager()
{
    m_pMouse = NULL;
    m_pDI = NULL;
    m_pKB = NULL;
}

CInputManager::~CInputManager()
{

}

bool CInputManager::Update( uint32 delta )
{
    memcpy( &m_lastinputinfo, &m_inputinfo, sizeof( InputInfo) );
    m_inputinfo.Reset();
    DIMOUSESTATE MouseState;
    HRESULT hr = -1;
    hr = m_pMouse->Poll();
    if( FAILED(hr) )
    {
        hr = m_pMouse->Acquire();
        if( FAILED(hr) )
            return false;
    }
    (m_pMouse->GetDeviceState( sizeof(DIMOUSESTATE), &MouseState ));
 //   m_inputinfo.MousePos.x += MouseState.lX;
	//m_inputinfo.MousePos.y += MouseState.lY;
    ComputeMousePos();
    m_inputinfo.MouseWheel.keyed = MouseState.lZ!=0;
    m_inputinfo.MouseWheel.param1 = MouseState.lZ;
    m_inputinfo.LButton.keyed = MouseState.rgbButtons[0]!=0;
    
    hr = m_pKB->Poll();
    if( FAILED(hr) )
    {
        hr = m_pKB->Acquire();
        if( FAILED(hr) )
            return false;
    }
    (m_pKB->GetDeviceState( sizeof(m_inputinfo.KeyBoard), &m_inputinfo.KeyBoard ));
    return true;
}

const InputInfo & CInputManager::GetInputInfo()
{
	return m_inputinfo;
}

void CInputManager::Initialize()
{
    HRESULT hr = -1;
    HMODULE hModule = ::GetModuleHandle(NULL);
    HWND hwnd = GetTopWindow( 0 );
    ( DirectInput8Create( hModule, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&m_pDI, NULL ));

    (m_pDI->CreateDevice( GUID_SysMouse, &m_pMouse, NULL ));
    (m_pMouse->SetDataFormat( &c_dfDIMouse) );
    (m_pMouse->SetCooperativeLevel( hwnd, DISCL_NONEXCLUSIVE | DISCL_BACKGROUND ));
    
    (m_pDI->CreateDevice( GUID_SysKeyboard, &m_pKB, NULL ));
    (m_pKB->SetDataFormat( &c_dfDIKeyboard) );
    (m_pKB->SetCooperativeLevel( hwnd, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE) );
    
    m_inputinfo.Reset();
    m_lastinputinfo.Reset();
    ComputeMousePos();
}

void CInputManager::Reset()
{
    SAFE_RELEASE(m_pDI);
    SAFE_RELEASE(m_pKB);
    SAFE_RELEASE(m_pMouse);
}

void CInputManager::ComputeMousePos()
{
    WINDOWINFO info;
    GetWindowInfo( CD3DManager::Instance().GetHwnd(), &info );
    //if( GetTopWindow(0) == CD3DManager::Instance().GetHwnd() )
    //    ClipCursor( &info.rcClient );
    //else
    //    ClipCursor( 0 );
    m_inputinfo.Reset();
    POINT p;
    GetCursorPos( &p );
    p.x = p.x - info.rcClient.left;
    p.y = p.y - info.rcClient.top;
    m_inputinfo.WindowMouse.x = p.x;
    m_inputinfo.WindowMouse.y = p.y;
    //ScaleByPoint((int&)p.x, (int&)p.y, (int)gc.windowsrect.Center().x, (int)gc.windowsrect.Center().y, \
    //    (float)gc.screenrect.Width()/(float)gc.windowsrect.Width(), (float)gc.screenrect.Height()/(float)gc.windowsrect.Height());
    p.x = (long)gc.screenrect.Width()*p.x/(long)gc.windowsrect.Width();
    p.y = (long)gc.screenrect.Height()*p.y/(long)gc.windowsrect.Height();
    m_inputinfo.GameMouse.x = p.x;
    m_inputinfo.GameMouse.y = p.y;

    p.x = p.x + gc.screenrect.x1;
    p.y = p.y + gc.screenrect.y1;
    IRect r( p.x, p.y, p.x, p.y );
    CMapManager::Instance().ConvertToOriginalCoord( r );

    m_inputinfo.MapMouse.x = r.x1;
    m_inputinfo.MapMouse.y = r.y1;

    if( IsKeyPressing( DIK_LBUTTON ) )
    {
        m_inputinfo.MapAreaMouse.x2 = r.x1;
        m_inputinfo.MapAreaMouse.y2 = r.y1;
    }
    else
    {
        m_inputinfo.MapAreaMouse.x1 = r.x1;
        m_inputinfo.MapAreaMouse.y1 = r.y1;
        m_inputinfo.MapAreaMouse.x2 = m_inputinfo.MapAreaMouse.x1;
        m_inputinfo.MapAreaMouse.y2 = m_inputinfo.MapAreaMouse.y1;
    }
}

POINT & CInputManager::GetMousePos()
{
    return m_inputinfo.GameMouse;
}

bool CInputManager::IsKeyPressed( int key )
{
    switch(key)
    {
    case DIK_LBUTTON:
        return (!m_inputinfo.LButton.keyed)&&(m_lastinputinfo.LButton.keyed);
    case DIK_RBUTTON:
        return (!m_inputinfo.RButton.keyed)&&(m_lastinputinfo.RButton.keyed);
    case DIK_MBUTTON:
        return (!m_inputinfo.MouseWheel.keyed)&&(m_lastinputinfo.MouseWheel.keyed);
    default:
        break;
    }
    if( key >= 0 && key < 0xff )
        return (!m_inputinfo.KeyBoard[key])&&(m_lastinputinfo.KeyBoard[key]);
    return false;
}

bool CInputManager::IsKeyPressing( int key )
{
    switch(key)
    {
    case DIK_LBUTTON:
        return (m_inputinfo.LButton.keyed);
    case DIK_RBUTTON:
        return (m_inputinfo.RButton.keyed);
    case DIK_MBUTTON:
        return (m_inputinfo.MouseWheel.keyed);
    default:
        break;
    }
    if( key >= 0 && key < 0xff )
        return m_inputinfo.KeyBoard[key]!=0;
    return false;
}